//============================================================================
// Name        : citar_pacientes.cpp
// Author      : 
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include "libreria.h"
#include <sstream>
using namespace std;

//ficheros:

FILE *citas;
FILE *punteros;
FILE *indice;
FILE *codigos;
FILE *pila;



//funciones:l
void abrir_ficheros(bool);
void cerrar_ficheros();
void cargar_datos();
void citar_paciente();
void leer_datos(string&,long int&,bool);
string pasa_a_string(int number);
void generar_horas_de_cita(string fecha_cita,vector<string> &citas_dia);
void escribir_ficheros();


//definiciones:
typedef map<string, int, less<string> > tipo_mapa_citas;
typedef map<long int, bool, less<long int> > tipo_mapa_pacientes;

//variables globales:
tipo_mapa_citas mapa_citas;
tipo_cita revision;
tipo_mapa_pacientes mapa_pacientes;
int total,borrados,ultimo_borrado,registros_historial;
vector<int> apilados;


//comienzo del main:
int main() {
	abrir_ficheros(true);
	cargar_datos();
	citar_paciente();
	cerrar_ficheros();
	abrir_ficheros(false);
	escribir_ficheros();
	cerrar_ficheros();
	system("pause");
	return 0;
}

void abrir_ficheros(bool es_lectura)
{	//abre todos los ficheros
	//los ficheros se van a abrir en modo lectura
	if(es_lectura==true)
	{
		if ((citas=fopen("..\\..\\datos\\citas.dat","r+b"))==NULL)
			printf("El fichero citas no se puede abrir\n");
		if ((punteros=fopen("..\\..\\datos\\punteros.dat","r"))==NULL)
			printf("El fichero punteros no se puede abrir\n");
		if ((indice=fopen("..\\..\\datos\\indice.dat","r"))==NULL)
			printf("El fichero indice no se puede abrir\n");
		if ((codigos=fopen("..\\..\\datos\\codigos.dat","r"))==NULL)
			printf("El fichero codigos no se puede abrir\n");
		pila=fopen("..\\..\\datos\\pila.dat","r");


	}
	else
	{//tenemos que asegurarnos antes que tenemos todos los datos de los ficheros secuenciales en memoria

		if ((citas=fopen("..\\..\\datos\\citas.dat","r+b"))==NULL)
			printf("El fichero citas no se puede abrir\n");
		if ((punteros=fopen("..\\..\\datos\\punteros.dat","w"))==NULL)
			printf("El fichero punteros no se puede abrir\n");
		if ((indice=fopen("..\\..\\datos\\indice.dat","w"))==NULL)
			printf("El fichero indice no se puede abrir\n");
		if ((pila=fopen("..\\..\\datos\\pila.dat","w"))==NULL)
			printf("El fichero pila no se puede abrir\n");


	}
}//final

void cargar_datos()
{
	long int id;
	int borrado;
	char fecha_hora[14];
	string auxiliar;
	int posicion;
	while(!feof(codigos))
	{
		fscanf(codigos,"%ld\n",&id);
		mapa_pacientes.insert(pair<long int,bool>(id,false));
	}
	while(!feof(indice))
	{
		fscanf(indice,"%s >>> %d\n",fecha_hora,&posicion);
		auxiliar=fecha_hora; //pasamos de char* a string STL
		mapa_citas.insert(pair<string,int>(auxiliar,posicion));
		auxiliar.clear();
	}
	fscanf(punteros,"%d %d\n",&total,&borrados);
	fscanf(punteros,"%d",&registros_historial);
	if (borrados!=0)
	{
		while(!feof(pila))
		{
			fscanf(pila,"%d\n",&borrado);
			apilados.push_back(borrado);
		}
		ultimo_borrado=apilados.back();
		apilados.pop_back();
	}
}

void leer_datos(string &fecha,long int &id,bool nueva_cita)
{		//el filtro se realiza mejor con un string y despues pasar a long int
	int ano,mes,dia;
	bool encontrado;

	if(nueva_cita==true)
	{
		do{
			do {
				cout<<"Introduce el codigo numerico del paciente:"<<endl;
				id=leer_entero();
			}while(id<=99999 || id > 999999);
			encontrado=false;
			if (mapa_pacientes.find(id)!=mapa_pacientes.end())
				encontrado=true;
		}while(encontrado==false);

	}
	//lectura fecha
	cout<<"Introduce la fecha de la cita:"<<endl;
	do{
		cout<<"Anno: ";
		ano=leer_entero();
	}while(ano<2013 || ano>2023);
	do{
		cout<<"Mes: ";
		mes=leer_entero();
	}while(mes<1 || mes>12);
	do{
		cout<<"Dia: ";
		dia=leer_entero();
	}while(dia<1 || dia>31);
	fecha=fecha+pasa_a_string(ano);
	fecha.push_back('-');
	if(mes>=10)
		fecha=fecha+pasa_a_string(mes);
	else
		fecha=fecha+"0"+pasa_a_string(mes);
	fecha.push_back('-');
	if(dia>=10)
		fecha=fecha+pasa_a_string(dia);
	else
		fecha=fecha+"0"+pasa_a_string(dia);

}


void citar_paciente()
{
	string fecha_cita,hora_a_buscar;
	vector<string> citas_en_dia,horas_disponibles;
	vector<string>::iterator itr;
	tipo_mapa_citas::iterator itr_citas;
	long int id=0;
	int posicion;
	bool tiene_cita_para_ese_dia,pide_id=true;
	tipo_cita estructura;
	int contador=1,eleccion;
	char tratamiento[100];
	do{
		//limpiar datos anteriores
		fecha_cita.clear();
		citas_en_dia.clear();
		horas_disponibles.clear();

		leer_datos(fecha_cita,id,pide_id); //true si se pide el id del paciente, false si se guarda
		generar_horas_de_cita(fecha_cita,citas_en_dia);

		for (itr=citas_en_dia.begin();itr!=citas_en_dia.end();itr++)
		{
			tiene_cita_para_ese_dia=false;
			hora_a_buscar=(*itr);
			if(mapa_citas.find(hora_a_buscar)!=mapa_citas.end())
			{//existe una cita para tal hora
				itr_citas=mapa_citas.find(hora_a_buscar);
				posicion=(*itr_citas).second;

				fseek(citas,(posicion-1)*sizeof(tipo_cita),0);
				fread(&estructura,sizeof(tipo_cita),1,citas);
				if (estructura.cod_paciente == id)
				{
					cout<<"El paciente ya tiene una cita para este dia"<<endl;

					tiene_cita_para_ese_dia=true;
					break;
				}
			}
			else
			{ //en este vector se almacena las horas de la cita disponibles y se van a usar en el caso de que el cliente no tiene cita ese dia
				horas_disponibles.push_back((*itr));
			}
		}
		//si todas las citas para ese dia estan cogidas:
		if (horas_disponibles.empty() && tiene_cita_para_ese_dia==false)
		{
			cout<<"No hay horas disponibles para este dia"<<endl;
			tiene_cita_para_ese_dia=true;
		}

		if (tiene_cita_para_ese_dia==false)
		{//hace la cita
			cout<<"Elige una fecha y hora:"<<endl;
			for(itr=horas_disponibles.begin();itr!=horas_disponibles.end();itr++)
			{
				cout<<contador<<").\t"<<(*itr)<<endl;
				contador++;
			}
			cout<<"________________"<<endl;
			eleccion=leer_entero();
			cout<<"Introduce el tratamiento:"<<endl;
			string trat;
			fflush(stdin); //se tiene que hacer fflush para que no use el buffer
			 getline (cin,trat); //se usa para leer tambien los espacios
			 strcpy(tratamiento,trat.c_str()); //pasa de string STR a char*
			 fflush(stdin);
			//llenamos la estructura con los datos para hacer la insercion en el fichero:
			revision.cod_paciente=id;
			strcpy(revision.tratamiento,tratamiento);
			revision.marca='A';
			if(borrados==0)
			{
				//ESTAMOS EN EL CASO DE QUE NO HAY BORRADOS:

				total++;  //se incrementa el numero de citas en uno
				mapa_citas.insert(pair<string,int>(horas_disponibles[eleccion-1],total));
			}
			else
			{
				//CASO DE QUE HAY BORRADOS:
				total++;
				borrados--;
				mapa_citas.insert(pair<string,int>(horas_disponibles[eleccion-1],ultimo_borrado)); //la posicion proviene de la pila
			}
		}
		pide_id=false;
		horas_disponibles.clear();
		citas_en_dia.clear();
	}while (tiene_cita_para_ese_dia==true);


}

void generar_horas_de_cita(string fecha_cita,vector<string> &citas_dia)
{
	citas_dia.clear();
	char horas[8][3]={"11","12","13","14","16","17","18","19"};
	for (int i=0;i<8;i++)
	{
		citas_dia.push_back(fecha_cita+'-'+horas[i]);
	}
}

string pasa_a_string(int number)
{
	stringstream ss;//create a stringstream
	ss << number;//add number to the stream
	return ss.str();//return a string with the contents of the stream
}

void escribir_ficheros()
{
	//para punteros
	fprintf(punteros,"%d %d\n",total,borrados);
	fprintf(punteros,"%d",registros_historial);
	//para indice_citas
	tipo_mapa_citas::iterator itr;
	for(itr=mapa_citas.begin();itr!=mapa_citas.end();itr++)
	{
		fprintf(indice,"%s >>> %d\n",(*itr).first.c_str(),(*itr).second); //con el metodo .c_str() pasamos a cadena de tipo char
	}
	//para citas
	if(borrados==0)
	{//CASO DE QUE NO HAY BORRADOS:
		fseek(citas,0,2); //nos colocamos en el final del fichero
		fwrite(&revision,sizeof(tipo_cita),1,citas);
	}
	else
	{
		//CASO DE QUE HAY BORRADOS:
		fseek(citas,(ultimo_borrado-1)*sizeof(tipo_cita),0); //nos colocamos en la posicion del ultimo borrado
		fwrite(&revision,sizeof(tipo_cita),1,citas);
	}

	//para pila
	for(unsigned int i=0;i<apilados.size();i++)
	{
		fprintf(pila,"%d\n",apilados[i]);
	}
}

void cerrar_ficheros()
{
	fclose(pila);
	fclose(punteros);
	fclose(indice);
	fclose(codigos);
	fclose(citas);
}


